// MsgOutPut.cpp : implementation file
//

#include "stdafx.h"
#include "MsgOutPut.h"
#include "process.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMsgOutPut


CMsgOutPut::CMsgOutPut()
{
	m_pWnd = NULL;

	ZeroMemory(&m_stuTbl, sizeof (LOG_TABLE));
}

CMsgOutPut::~CMsgOutPut()
{
	// close the DB
	m_dbSQLite.close();
}


BEGIN_MESSAGE_MAP(CMsgOutPut, CEdit)
	//{{AFX_MSG_MAP(CMsgOutPut)

	//}}AFX_MSG_MAP
	ON_WM_CREATE()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMsgOutPut message handlers

int CMsgOutPut::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEdit::OnCreate(lpCreateStruct) == -1)
		return -1;
	/*
    m_wndVScrollBar.Create(WS_CHILD| SBS_VERT|WS_VISIBLE,CRect(),
	this,ID_VSCROLLBAR);
/*    m_wndHScrollBar.Create(WS_CHILD| SBS_HORZ|WS_VISIBLE,CRect(),
//	this,ID_HSCROLLBAR);

   SCROLLINFO info;
   info.cbSize = sizeof(SCROLLINFO);     
   info.fMask  = SIF_ALL;     
   info.nMin   = 0;     
   info.nMax   = 100; 
   info.nPage  = 0;     
   info.nPos   = 0;    
   info.nTrackPos = 2; 
   m_wndHScrollBar.SetScrollInfo(&info);

   SCROLLINFO info1;
   info1.cbSize = sizeof(SCROLLINFO);     
   info1.fMask  = SIF_ALL;     
   info1.nMin   = 0;     
   info1.nMax   = 0; 
   info1.nPage  = 10;     
   info1.nPos   = 0;    
   info1.nTrackPos = 2; 

   m_wndVScrollBar.SetScrollInfo(&info1);
*/

   CFont nfont;
   nfont.CreatePointFont(10,"Courier");
   GetDC()->SelectObject(nfont);
   SetFont(&nfont);
   return 0;
}



void CMsgOutPut::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
  /*// Get the minimum and maximum scroll-bar positions.
   int minpos;
   int maxpos;
   m_wndHScrollBar.GetScrollRange(&minpos, &maxpos); 
   maxpos = m_wndHScrollBar.GetScrollLimit();

   // Get the current position of scroll box.
   int curpos = pScrollBar->GetScrollPos();

   // Determine the new position of scroll box.
   switch (nSBCode)
   {
   case SB_LEFT:      // Scroll to far left.
      curpos = minpos;
      break;

   case SB_RIGHT:      // Scroll to far right.
      curpos = maxpos;
      break;

   case SB_ENDSCROLL:   // End scroll.
      break;

   case SB_LINELEFT:      // Scroll left.
      if (curpos > minpos)
         curpos--;
      break;

   case SB_LINERIGHT:   // Scroll right.
      if (curpos < maxpos)
         curpos++;
      break;

   case SB_PAGELEFT:    // Scroll one page left.
   {
      // Get the page size. 
      SCROLLINFO   info;
      m_wndHScrollBar.GetScrollInfo(&info, SIF_ALL);
   
      if (curpos > minpos)
      curpos = max(minpos, curpos - (int) info.nPage);
   }
      break;

   case SB_PAGERIGHT:      // Scroll one page right.
   {
      // Get the page size. 
      SCROLLINFO   info;
      m_wndHScrollBar.GetScrollInfo(&info, SIF_ALL);

      if (curpos < maxpos)
         curpos = min(maxpos, curpos + (int) info.nPage);
   }
      break;

   case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
      curpos = nPos;      // of the scroll box at the end of the drag operation.
      break;

   case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
      curpos = nPos;     // position that the scroll box has been dragged to.
      break;
   }

   // Set the new position of the thumb (scroll box).
   m_wndHScrollBar.SetScrollPos(curpos);
*/
  CEdit::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CMsgOutPut::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	/*
        // Get all the vertial scroll bar information
	     SCROLLINFO si; 

         si.cbSize = sizeof (si);
         si.fMask  = SIF_ALL;
         m_wndVScrollBar.GetScrollInfo (&si);
//         int yChar;
         // Save the position for comparison later on
         int yPos = si.nPos;

         switch (nSBCode)
         {
         // user clicked the HOME keyboard key
         case SB_TOP:
              si.nPos = si.nMin;
              break;
              
         // user clicked the END keyboard key
         case SB_BOTTOM:
              si.nPos = si.nMax;
              break;
              
         // user clicked the top arrow
         case SB_LINEUP:
              si.nPos -= 1;
              break;
              
         // user clicked the bottom arrow
         case SB_LINEDOWN:
              si.nPos += 1;
              break;
              
         // user clicked the shaft above the scroll box
         case SB_PAGEUP:
              si.nPos -= si.nPage;
              break;
              
         // user clicked the shaft below the scroll box
         case SB_PAGEDOWN:
              si.nPos += si.nPage;
              break;
              
         // user dragged the scroll box
         case SB_THUMBTRACK:
              si.nPos = si.nTrackPos;
              break;
              
         default:
              break; 
         }

         // Set the position and then retrieve it.  Due to adjustments
         //   by Windows it may not be the same as the value set.
         si.fMask = SIF_POS;
         m_wndVScrollBar.SetScrollInfo (&si, TRUE);
         /*m_wndVScrollBar.GetScrollInfo (&si);

         // If the position has changed, scroll window and update it
         if (si.nPos != yPos)
         {                    
          ScrollWindow(0, yChar * (yPos - si.nPos), NULL, NULL);
          UpdateWindow ();
         }*/

	CEdit::OnVScroll(nSBCode, nPos, pScrollBar);
}


void CMsgOutPut::OnContextMenu(CWnd* pWnd,CPoint pos )
{
	// theApp.ShowPopupMenu(IDR_OUTPUT_MENU, pos, this);
	OutputDebugString("\nvoid CMsgOutPut::OnContextMenu(CWnd* pWnd,CPoint pos )");
}


void CMsgOutPut::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags)
{
   if(nChar == VK_LEFT || nChar == VK_RIGHT || nChar == VK_UP || nChar == VK_DOWN)
	   CEdit::OnKeyDown(nChar,nRepCnt,nFlags);
}


void CMsgOutPut::OutPut(LPCTSTR szpText)
{
	int			nRows = 0;
	char		tmpbuf[128] = {0}; 
	char		szSQL[MAX_SQL_STMT*2] = {0};
	char		sztTxt[MAX_SQL_STMT] = {0};
	

	CString		strTemp = szpText;

	strTemp += _T("\r\n");
	int len  = GetWindowTextLength();

	SetSel(len,len);
	ReplaceSel(strTemp);
	

	// log message to DB.
	if ( strlen(m_stuTbl.szTblFile) > 0)
	{
		_strtime( tmpbuf );

		NormalizeSQL(szpText, sztTxt);

		sprintf (szSQL, "INSERT INTO '%s' VALUES (0, '%s', '%s');", 
				m_stuTbl.szTblName, 
				tmpbuf,
				sztTxt
				);

		try
		{
			nRows = m_dbSQLite.execDML(szSQL);	
		}
		catch (CppSQLite3Exception &e)
		{
			DbgPrintf (true, " %s. \n", e.errorMessage());
		}

		OutputDebugString (szSQL);
		OutputDebugString ("\r\n");
	}
}

void CMsgOutPut::Odprintf(const char *fmt, ...)
{
    char buf[2048] = {0};
    va_list ap;

    va_start(ap, fmt);
	_vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

	// OutputDebugString(buf);
	OutPut(buf);
}


void CMsgOutPut::DbgPrintf(BOOL bPrompt, const char *fmt, ...)
{
    char buf[2048] = {0};
    va_list ap;
	
    va_start(ap, fmt);
	_vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
	
	OutputDebugString(buf);

	if (bPrompt)
	{
		SetForegroundWindow();
		MessageBox(buf, "SQL error", MB_OK | MB_ICONERROR);
	}
}


LRESULT CMsgOutPut::OnUpmFinish(WPARAM wParam, LPARAM lParam)
{
	DWORD status = (DWORD)wParam;
	UINT pid     = (UINT)lParam;
	
	// m_pWnd
	return 0;
}


void CMsgOutPut::SetDBFile(LPCTSTR strFile)
{
	CString		strDBFile;
	char		szSQL[MAX_SQL_STMT] = {0};

	// construct the full path.
	if (strFile[1] == ':' || strlen(strFile) == 0)
	{
		strcpy(m_stuTbl.szTblFile, strFile);
	}
	else
	{
		GetAppDir(strDBFile);
		
		sprintf(m_stuTbl.szTblFile, "%s%s", strDBFile, strFile);
	}
		

	strcpy(m_stuTbl.szTblName, GetRandTableName());

	try
	{	
		// close the DB
		m_dbSQLite.close();

		// create new table in this DB.
		m_dbSQLite.open (m_stuTbl.szTblFile);

		sprintf (szSQL, 
				"CREATE TABLE '%s' (type int, time char (32), content char (1024));", 
				m_stuTbl.szTblName);

		m_dbSQLite.execDML(szSQL);	
	}
	catch (CppSQLite3Exception &e)
	{
		DbgPrintf (true, " %s. \n", e.errorMessage());
	}	
}

void CMsgOutPut::GetAppDir(CString &strPath)
{
    TCHAR   sDrive[_MAX_DRIVE] = {0};  
    TCHAR   sDir[_MAX_DIR] = {0};
    TCHAR   sFilename[_MAX_FNAME] = {0}, Filename[_MAX_FNAME] = {0};  
    TCHAR   sExt[_MAX_EXT] = {0};  

    GetModuleFileName(AfxGetInstanceHandle(), Filename, _MAX_PATH);
	
    _tsplitpath(Filename, sDrive, sDir, sFilename, sExt);  

    CString   homeDir(CString(sDrive)   +   CString(sDir));  
    
	int   nLen   =   homeDir.GetLength();  
    
	if(homeDir.GetAt(nLen-1)   !=   _T('\\'))  
      homeDir   +=   _T('\\');  

	strPath = homeDir;
}

char * CMsgOutPut::GetRandTableName()
{
	static char szTblName[128] = {0};

	time_t tm_now = time(0);
	
	struct tm *ptm = localtime (&tm_now);

	sprintf (szTblName, "bw%04d%02d%02d_%02d%02d%02d_db", 
				ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
				ptm->tm_hour, ptm->tm_min, ptm->tm_sec
			);

	return szTblName;
}

void CMsgOutPut::NormalizeSQL(LPCTSTR strSrc, LPCTSTR strDst)
{
	char *psrc = (char *)strSrc;
	char *pdst = (char *)strDst;

	while (*psrc)
	{
		if (*psrc == '\'')
		{
			*pdst++ = '\'';
		}

		*pdst++ = *psrc++;		
	}

	*pdst = 0x0;
}
